import { INestApplication } from '@nestjs/common';
import { FastifyAdapter } from '@nestjs/platform-fastify';
import { Test } from '@nestjs/testing';
import { FastifyInstance } from 'fastify';
import { AppModule as PostsModule } from '../plugins/graphql-federation-plugin/posts-service/federation-posts.module';
import { AppModule as UsersModule } from '../plugins/graphql-federation-plugin/users-service/federation-users.module';
import {
  BASE_PLUGIN_URL,
  NEW_PLUGIN_URL,
} from '../plugins/mocks/utils/constants';

describe('GraphQL Federation with plugins', () => {
  let app: INestApplication;

  describe('UsersService', () => {
    beforeEach(async () => {
      const module = await Test.createTestingModule({
        imports: [UsersModule],
      }).compile();

      app = module.createNestApplication(new FastifyAdapter());
      await app.init();
    });

    it('should get the plugin for users', async () => {
      const fastifyInstance: FastifyInstance = app
        .getHttpAdapter()
        .getInstance();
      await fastifyInstance.ready();

      const response = await fastifyInstance.inject({
        method: 'GET',
        url: NEW_PLUGIN_URL,
      });
      const data = JSON.parse(response.body);
      expect(fastifyInstance.printPlugins().includes('mockPlugin')).toBe(true);
      expect(response.statusCode).toBe(200);
      expect(data.from).toBe(NEW_PLUGIN_URL);
    });
  });

  describe('PostsService', () => {
    beforeEach(async () => {
      const module = await Test.createTestingModule({
        imports: [PostsModule],
      }).compile();

      app = module.createNestApplication(new FastifyAdapter());
      await app.init();
    });

    it('should get the plugin for posts', async () => {
      const fastifyInstance: FastifyInstance = app
        .getHttpAdapter()
        .getInstance();
      await fastifyInstance.ready();

      const response = await fastifyInstance.inject({
        method: 'GET',
        url: BASE_PLUGIN_URL,
      });
      const data = JSON.parse(response.body);
      expect(fastifyInstance.printPlugins().includes('mockPlugin')).toBe(true);
      expect(response.statusCode).toBe(200);
      expect(data.from).toBe(BASE_PLUGIN_URL);
    });
  });

  afterEach(async () => {
    await app.close();
  });
});
